home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 011 / miscutl1.arc / LIST.AQM / LIST.ASM
Assembly Source File  |  1984-04-08  |  14KB  |  393 lines

  1.          PAGE    60,80
  2.          TITLE   LIST --- Replace TYPE and MORE commands
  3. ;=====================================================================
  4. ; Name:     LIST, display contents of an ASCII file.
  5. ; Syntax:
  6. ;           LIST  <[d:]filename[.ext]>
  7. ; Input:
  8. ;           An ASCII file of any size may be listed, however only the
  9. ;           first 80 bytes of each record is displayed.
  10. ;
  11. ;           After the 'More?' prompt, enter a CR to continue, or
  12. ;           any other character to terminate.
  13. ; Output:
  14. ;           Logical records (ending in LF and/or CR) are placed into
  15. ;           the screen buffer.
  16. ; Notes:
  17. ;           File CONFIG.SYS is required and should have:
  18. ;                        DEVICE=ANSI.SYS
  19. ;           Written for the IBM PC by Vernon Buerg, November 1983,
  20. ;           and is supplied for public domain use.
  21. ;=====================================================================
  22. ;
  23. STACK    SEGMENT PARA STACK 'STACK'
  24.          DB      128 DUP (0)
  25. STACK    ENDS
  26. ;
  27. DATA     SEGMENT PUBLIC PARA 'DATA'
  28. ASKFILE  DB      13,10,'Enter filename.ext:$'
  29. CLEAR    DB      27,'[2J$'
  30. PROMPT   DB      27,'[25;1H','More?$'
  31. EOFMSG   DB      27,'[25;1HEnd-of-file$'
  32. CODE2    DB      'File not found$'
  33. CODE3    DB      'Path not found$'
  34. KEYIN    DB      0            ;keyboard buffer size
  35. KEYOUT   DB      0            ;keyboard length read
  36. FILENAME DB      16 DUP (0)   ;drive:filename.ext
  37. HANDLE   DW      0            ;file handle from open
  38. COL      DW      1            ;current display column
  39. ROW      DW      3            ;current display row
  40. INDEX    DW      0            ;offset in buffer to record
  41. ;
  42. OPENMSG  DB      'Open code: '
  43. OPENCODE DW      '00'
  44.          DB      '  $'
  45. RECLEN   DW      0            ;length of current record
  46. RECADDR  DW      0            ;addr of i/o buffer
  47. ;
  48. SWITCH1  DB      0
  49. EOR      EQU     1            ;end-of-record
  50. SWITCH2  DB      0
  51. NODATA   EQU     2            ;null record
  52. NUMLF    DB      1            ;line feed count
  53. NUMCR    DB      0            ;C/R count
  54. WORK     DB      256 DUP (?)  ;current logical record
  55. DATA     ENDS
  56. ;
  57. ZBUFFER  SEGMENT PARA PUBLIC 'BUFFER'
  58. RECORDS  DB      65535 DUP (?)
  59. ZBUFFER  ENDS
  60. ;
  61. BIOS     SEGMENT AT 40H       ;set up labels to determine
  62.          ORG     10H          ;color or monochrome card
  63. EQFLAG   LABEL   WORD
  64.          ORG     4AH          ;40 or 80 column display
  65. NCLMS    LABEL   WORD
  66.          ORG     63H
  67. A6845    LABEL   WORD         ;points to video card ports
  68. BIOS     ENDS
  69. ;
  70.          PAGE
  71. CSEG     SEGMENT PARA PUBLIC 'CODE'
  72.          ASSUME  CS:CSEG,DS:DATA,SS:STACK,ES:ZBUFFER
  73. LIST     PROC    FAR
  74.          PUSH    DS           ;save for linkage
  75.          XOR     AX,AX        ;clear for return
  76.          PUSH    AX           ;put in stack
  77. ;
  78.          MOV     AX,DATA      ;Addr of work areas
  79.          MOV     DS,AX        ;Set data segment reg
  80. ;
  81.          PUSH    DS           ;Save DS
  82.          XOR     CX,CX        ;clear hi-byte
  83.          MOV     CL,BYTE PTR ES:[80H]  ;Length of command parm
  84.          DEC     CL           ;For ending CR
  85.          CMP     CL,0         ;Any parm string?
  86.          JLE     GETNAME      ;No, ask for it
  87. ;
  88.          MOV     SI,82H       ;Offset to command parm string
  89.          MOV     DI,OFFSET FILENAME
  90.          MOV     AX,DS        ;Swap DS/ES
  91.          MOV     BX,ES
  92.          MOV     DS,BX        ;Copy command string
  93.          MOV     ES,AX
  94.          REP     MOVSB
  95.          POP     DS           ;Restore DS
  96.          JMP     OPEN
  97.          PAGE
  98. ;  No filename supplied with command
  99. ;
  100. GETNAME: POP     DS
  101.          MOV     DX,OFFSET ASKFILE    ;Prompt for file name
  102.          MOV     AH,9
  103.          INT     21H
  104.          MOV     AH,0AH       ;Buffered kybd input DOS req
  105.          MOV     DX,OFFSET KEYIN
  106.          MOV     KEYIN,15     ;Size of buffer
  107.          INT     21H
  108. ;
  109.          XOR     BX,BX
  110.          MOV     BL,KEYOUT    ;Number of chars read
  111.          CMP     BL,0
  112.          JE      GETNAME
  113.          MOV     FILENAME[BX],0 ;overlay CR
  114.          PAGE
  115. ;
  116. OPEN:    MOV     DX,OFFSET FILENAME      ;file to open
  117.          MOV     AX,2         ;for read/write
  118.          MOV     AH,3DH       ;open a file
  119.          INT     21H
  120.          MOV     HANDLE,AX    ;save file handle
  121. ;
  122.          JNC     INIT         ;if OPEN okay
  123.          MOV     DX,OFFSET CODE2
  124.          CMP     AL,2         ;is it 'file not found'?
  125.          JE      ERROR
  126.          MOV     DX,OFFSET CODE3
  127.          CMP     AL,2         ;is it 'PATH NOT FOUND'?
  128.          JE      ERROR
  129. ;
  130.          AAM
  131.          XCHG    AL,AH
  132.          OR      OPENCODE,AX
  133.          MOV     DX,OFFSET OPENMSG
  134. ERROR:   MOV     AH,9
  135.          INT     21H          ;say OPEN FAILED
  136.          RET
  137.          PAGE
  138. ;
  139. ; Initialize buffer to EOF stoppers
  140. ;
  141. INIT:    MOV     BX,ZBUFFER   ;addr of I/O area
  142.          MOV     RECADDR,BX   ;save it
  143.          MOV     DX,OFFSET CLEAR
  144.          MOV     AH,9
  145.          INT     21H          ;to clear screen
  146. ;
  147. READAGN: MOV     CX,65535     ;number of bytes to clear
  148.          MOV     ES,RECADDR
  149. ;
  150. STOPPER: MOV     DI,CX
  151.          MOV     ES:BYTE PTR[DI],1AH    ;fill with stoppers
  152.          LOOP    STOPPER
  153.          PAGE
  154. ;
  155. ; Read a block  (64K)
  156. ;
  157.          MOV     BX,HANDLE       ;get file handle from open
  158.          MOV     DX,RECADDR      ;offset to record buffer
  159.          PUSH    DS
  160.          MOV     DS,DX           ;set data segment ptr
  161.          SUB     DX,DX           ; with zero offset
  162.          MOV     CX,65534        ;number of bytes to read
  163.          MOV     AH,3FH          ;read from a file
  164.          INT     21H
  165. ;
  166.          POP     DS
  167. ;        MOV     BX,AX           ;Save length read
  168.          MOV     SWITCH1,0       ;reset EOR flag
  169.          MOV     INDEX,0         ;offset into buffer
  170.          CMP     AX,0            ;Any bytes read?
  171.          JNE     READ            ;Yes, list the buffer
  172.          JMP     CLOSE           ;No, all done
  173. ;
  174. ; Set next row and column for next display line
  175. ;
  176. READ:    INC     COL             ;spot for incomplete record
  177.          DEC     ROW
  178.          CMP     NUMLF,0         ;record ended in LF?
  179.          JE      GETNEXT         ;no, have col/row
  180.          INC     ROW             ;yes, row stays where it is
  181.          MOV     COL,1           ; and in column 1
  182. ;
  183. ; Extract next logical record from display
  184. ;
  185. GETNEXT: CALL    SCAN_BUF        ;Scan for logical record
  186.          MOV     CX,RECLEN       ;Record size
  187.          SUB     CL,NUMLF        ;for LF
  188.          SUB     CL,NUMCR        ;for CR
  189.          MOV     RECLEN,CX
  190.          CMP     CX,0            ;blank line?
  191.          JE      GETROW          ;yes, increment row only
  192. ;
  193.          LEA     SI,WORK         ;addr of record
  194.          MOV     AX,ROW          ;destination row
  195.          CALL    PRINT           ;put into screen buffer
  196. ;
  197. GETROW:  INC     ROW             ;bump to next row
  198.          MOV     AX,ROW          ;save row number
  199.          CMP     AL,25           ;exceeded screen?
  200.          JNE     TESTEOR         ;no, read next record
  201. ;
  202.          MOV     DX,OFFSET PROMPT
  203.          MOV     AH,9
  204.          INT     21H             ;say 'More?'
  205. ;
  206. ; Wait for keyboard input
  207. ;
  208.          MOV     AH,12           ;clear console
  209.          MOV     AL,7            ;and get a char
  210.          INT     21H             ;pause for enter
  211.          CMP     AL,0DH          ;want to quit?
  212.          JE      NXTPAGE         ;no, continue
  213. ;
  214.          CMP     AL,'N'          ;want to quit?
  215.          JE      CLOSE           ;yes, all done
  216. ;
  217.          CMP     AL,'n'
  218.          JE      CLOSE
  219. ;
  220. NXTPAGE: MOV     ROW,2           ;no, reset to first row
  221.          MOV     AX,ROW
  222. ;
  223.          MOV     DX,OFFSET CLEAR
  224.          MOV     AH,9
  225.          INT     21H             ;to clear screen
  226. ;
  227. ;        LEA     SI,WORK
  228. ;        MOV     AX,1            ;
  229. ;        MOV     CX,RECLEN        ; put last line as top line
  230. ;        CALL    PRINT           ;
  231. ;
  232. TESTEOR: TEST    SWITCH1,EOR     ;end-of-records?
  233.          JZ      READ
  234.          JMP     READAGN         ;yes, read next block
  235. ;
  236. CLOSE:   MOV     BX,HANDLE       ;file handle from open
  237.          MOV     AH,3EH          ;close a file handle
  238.          INT     21H
  239. ;
  240.          MOV     DX,OFFSET EOFMSG
  241.          MOV     AH,9
  242.          INT     21H             ;to say done
  243. ;
  244.          RET
  245.          PAGE
  246. SCAN_BUF PROC    NEAR
  247. ;
  248. ; Function: Scan the buffer for special characters and copy wanted
  249. ;        data to field WORK. A logical record ends in an LF and/or CR.
  250. ;
  251. ; Input: ZBUFFER (RECORDS) contains a block of data from the file
  252. ;        INDEX is the current offset to a logical record
  253. ; Output:
  254. ;        WORK contains a logical record
  255. ;        NUMLF contains number of line feeds (ignored)
  256. ;        NUMCR contains number of carriage returns (ignored)
  257. ;        RECLEN contains length of logical record
  258. ; Notes: Tabs are replaced by blanks;
  259. ;        lines beginning with hex-F are ignored
  260. ;
  261.          PUSH    ES
  262.          PUSH    CX
  263.          PUSH    SI
  264.          PUSH    DI
  265.          TEST    SWITCH1,EOR
  266.          JZ      SCAN1
  267.          JMP     SCAN_END
  268. ;
  269. SCAN1:   XOR     CX,CX
  270.          XOR     DI,DI
  271.          AND     SWITCH2,0FFH-NODATA
  272.          MOV     NUMLF,0         ;reset LF indicator
  273.          MOV     NUMCR,0         ;zero CR counter
  274.          MOV     AX,ZBUFFER
  275.          MOV     ES,AX           ;set addr of I/O buffer segment
  276. ;
  277. SCAN2:   MOV     SI,INDEX
  278.          MOV     AL,RECORDS[SI]  ;Get a byte
  279.          CMP     AL,1AH          ;End of buffer?
  280.          JNE     SCAN3
  281.          MOV     RECLEN,CX
  282.          OR      SWITCH1,EOR     ;Indicate end-of-records
  283.          JMP     SCAN_END
  284. ;
  285. SCAN3:   CMP     AL,9H           ;Is it TAB?
  286.          JNE     SCAN4
  287.          MOV     AL,' '          ;Yes, replace with blank
  288. ;
  289. SCAN4:   MOV     WORK[DI],AL     ;Store character
  290.          INC     DI              ;Increment pointer
  291.          INC     CX              ;Increment counter
  292.          INC     INDEX           ;Increment counter
  293. ;
  294.          CMP     AL,0DH          ;Is it a CR?
  295.          JNE     SCAN5
  296.          INC     NUMCR           ;Yes, increment counter
  297. SCAN5:   CMP     AL,' '
  298.          JE      SCAN7
  299.          CMP     AL,0AH          ;Is it line feed?
  300.          JNE     SCAN6
  301.          INC     NUMLF
  302.          JMP     SCAN8
  303. SCAN6:   OR      SWITCH2,NODATA  ;Non-space found
  304. ;
  305. SCAN7:   CMP     CX,255          ;Record too big?
  306.          JE      SCAN8           ;Chop record at 255 bytes
  307.          JMP     SCAN2
  308. ;
  309. SCAN8:   MOV     RECLEN,CX
  310.          CMP     WORK,0FH        ;If record begins with "sun"
  311.          JNE     SCAN9           ; symbol, skip it
  312.          JMP     SCAN1
  313. ;
  314. SCAN9:   TEST    SWITCH2,NODATA  ;If nothing but spaces found,
  315.          JNZ     SCAN_END        ; read another record
  316.          JMP     SCAN1
  317. ;
  318. SCAN_END:
  319.          POP     DI
  320.          POP     SI
  321.          POP     CX
  322.          POP     ES
  323.          RET
  324. ;
  325. SCAN_BUF ENDP
  326. ;
  327.          PAGE
  328.          ASSUME  CS:CSEG,DS:DATA,ES:NOTHING
  329. PRINT    PROC    NEAR
  330.          PUSH    ES
  331.          PUSH    DI
  332.          PUSH    DX
  333.          PUSH    SI
  334. ;
  335.          MOV     DI,COL          ;set column
  336.          DEC     DI              ;adjust for zero offset
  337.          DEC     AX              ;adjust row too
  338.          CMP     CL,0            ;null string?
  339.          JE      EXIT            ;if so,do nothing, Else,
  340. ;
  341.          MOV     BX,BIOS         ;get ready to determine card type
  342.          MOV     ES,BX           ;and number of columns
  343.          MUL     ES:NCLMS        ;AX = column * words per line
  344.          ADD     DI,AX           ;DI = words from start of screen
  345.          SHL     DI,1            ;adjust for attribute bytes
  346. ;
  347.          MOV     DX,ES:A6845     ;point to 6845 base port
  348.          ADD     DX,6            ;point to status port
  349. ;
  350. ;CX has the count of characters to write,
  351. ;SI points to the string data,
  352. ;DI points to a screen position
  353. ;
  354.          MOV     AX,0B800H       ;default to color card
  355.          MOV     BX,ES:EQFLAG
  356.          AND     BX,30H
  357.          CMP     BX,30H          ;is it monochrome?
  358.          JNE     CARDOK          ;no, go
  359.          MOV     AX,0B000H       ;yes, set for monochrome
  360. CARDOK:  MOV     ES,AX           ;points ES to video
  361. ;
  362. ;  DS:SI => first character of string
  363. ;  ES:DI => screen memory to display it
  364. ;  CX    => number of characters to display
  365. ;  DX    => status port of video card
  366. ;
  367. ;-------- Wait for horzontal retrace
  368. TESTLO:  IN      AL,DX           ;get status
  369.          TEST    AL,1            ;is it low?
  370.          JNZ     TESTLO          ;no, keep checking
  371.          CLI                     ;turn off interrupts
  372. TESTHI:  IN      AL,DX           ;get status
  373.          TEST    AL,1            ;is it high?
  374.          JZ      TESTHI          ;no, keep checking
  375. ;-------- Okay to write to screen now (no 'hash')
  376.          MOVSB                   ;[DS:DI]->[ES:DI],DI++,SI++,CX--
  377.          INC     DI              ;skip the attribute byte
  378.          LOOP    TESTLO          ;do till end of string
  379.          STI                     ;turn interrupts back on
  380. ;
  381. EXIT:    POP     SI
  382.          POP     DX
  383.          POP     DI
  384.          POP     ES
  385.          RET
  386. ;
  387. PRINT    ENDP
  388. ;
  389. LIST     ENDP
  390. CSEG     ENDS
  391. ;
  392.          END     LIST
  393.